package com.zhaoyu.admin.gateway.filter;

import com.zhaoyu.admin.gateway.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;

@Component // 存放到IOC容器中
@Log4j2
public class LoginAndRefreshTokenFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        /**
         * 1、获取请求对象和响应对象
         */
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        /**
         * 2、判断当前的请求是否为登录，如果是，直接放行
         */
        if(request.getURI().getPath().contains("/login/in")){ // 如果是去登录页面，直接放行/login/in 如果是/admin/login开头就不拦截
            // 放行
            return chain.filter(exchange);
        }

        /**
         * 3、获取当前用户的请求头jwt信息
         */
        HttpHeaders headers = request.getHeaders();
        String token1 = headers.getFirst("token");
        // List<String> token2 = headers.get("token");

        /**
         * 4、判断当前令牌是否存在
         */
        // token是空的或解析失败,后端请求结束,去登录页面
        if(StringUtils.isEmpty(token1) || JwtUtil.verifyToken(token1) == 1 || JwtUtil.verifyToken(token1) == 2){
        // if(StringUtils.isEmpty(token2.get(0)) || JwtUtil.verifyToken(token2.get(0)) == 1 || JwtUtil.verifyToken(token2.get(0)) == 2){
            // 如果token是空的或解析失败，向客户端返回错误提示信息
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

//        try {
//            /**
//             * 5、如果令牌存在，解析jppwt令牌，判断该令牌是否合法，如果不合法，则向客户端返回错误信息
//             */
//            int result = JwtUtil.verifyToken(token1); // 判断令牌是否过期
//            if (result == 0){ // 刷新token,完成续期
//                Integer id = JwtUtil.getId(token1); // 获取用户id
//                token1 = JwtUtil.getToken(id); // 重新生成token
//                headers.add("refresh_token", token1); // 重新设置token到header中
//                // request.getHeaders().set("refresh_token", token1); // 重新设置token到header中
//            }
//            /*
//            int result = JwtUtil.verifyToken(token2.get(0)); // 判断令牌是否过期
//            if(result == 0){ // 刷新token,完成续期
//                Integer id = JwtUtil.getId(token2.get(0)); // 获取用户id
//                token2 = Collections.singletonList(JwtUtil.getToken(id)); // 重新生成token
//                headers.add("refresh_token", token2.get(0)); // 重新设置token到header中
//                // request.getHeaders().set("refresh_token", token2.get(0)); // 重新设置token到header中
//            }
//            */
//        }catch (Exception e){
//            e.printStackTrace();
//            // 想客户端返回错误提示信息
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
//            return response.setComplete();
//        }

        try {
            /**
             * 5、如果令牌存在，解析jppwt令牌，判断该令牌是否合法，如果不合法，则向客户端返回错误信息
             */
            Claims claims = JwtUtil.getClaimsBody(token1); // 获取jwt中的claims信息
            int result = JwtUtil.verifyToken(claims); // 判断令牌是否过期
            if(result == 0 || result == -1){ // 如果有效，则放行
                // 5.1、合法，则向header中重新设置userId
                Integer id = (Integer) claims.get("id"); // 获取用户id
                // log.info("find userid:{} from uri:{}",id,request.getURI()); // 打印日志
                // 重新设置token到header中
                ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> { // 设置header
                    httpHeaders.add("userId", id + ""); // 设置userId
                }).build();
                exchange.mutate().request(serverHttpRequest).build(); // 构建新的请求对象
            }
            /*
            Claims claims = JwtUtil.getClaimsBody(token2.get(0)); // 获取jwt中的claims信息
            int result = JwtUtil.verifyToken(claims); // 判断令牌是否过期
            if(result == 0 || result == -1){ // 如果有效，则放行
                // 5.1、合法，则向header中重新设置userId
                Integer id = (Integer) claims.get("id"); // 获取用户id
                // log.info("find userid:{} from uri:{}",id,request.getURI()); // 打印日志
                // 重新设置token到header中
                ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> { // 设置header
                    httpHeaders.add("userId", id + ""); // 设置userId
                }).build();
                exchange.mutate().request(serverHttpRequest).build(); // 构建新的请求对象
            }
            */
        }catch (Exception e){
            e.printStackTrace();
            // 想客户端返回错误提示信息
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        /**
         * 6、解析，成功，登录有效，放行
         */
        return chain.filter(exchange);

    }

    /**
     * 优先级设置
     * 值越小，优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return -200;
    }

}